/* Nokia 6100 Color LCD routines
   Author: Martin Maly, www.uelectronics.info, author@uelectronics.info

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


  Target: Luminary Micro LM3S811
  Family: ARM7-TDMI Cortex M3
  Compiler: Keil ARM C
*/
//LCD12 - 12bit graphics routines for Nokia 6100 LCD family

#include "lcd.h"
#include "lcd12.h"
#include "font.h"

void LCD12_send2(word color);

void LCD12_hline (byte x0,byte x1,byte y,word color){
 int i;
 y+=2;
 
 x0 &= 0xfe;
 x1 &= 0xfe;
 
 sendCMD(PASET);
 sendData(y);
 sendData(y);
 sendCMD(CASET);
 sendData(x0);
 sendData(x1);
 sendCMD(RAMWR);
 for (i=x0>>1;i<(x1>>1);i++) LCD12_send2(color);
 LCD12_send2(color); //for sure
 sendCMD(0);
}

void LCD12_rectangle(byte x0,byte y0,byte x1,byte y1,word color){
 int i;
 i=((y1-y0+1) * (x1-x0+1))>>1;
 x0 &= 0xfe;
 x1 &= 0xfe;
 y0+=2;
 y1+=2;
 sendCMD(PASET);
 sendData(y0);
 sendData(y1);
 sendCMD(CASET);
 sendData(x0);
 sendData(x1);
 sendCMD(RAMWR);
 while (i) {LCD12_send2(color);i--;}
 sendCMD(NOP); //just for fun
}


void LCD12_blit(byte x,byte y,byte width,byte height,word *buffer){
 int i,j,c1,c2;
 y+=2;
 x &= 0xfe;
 sendCMD(PASET);
 sendData(y);
 sendData(y+height-1);
 sendCMD(CASET);
 sendData(x);
 sendData(x+width-1);
 sendCMD(RAMWR);
 for (i=0;i<height;i++){
  for (j=0;j<width;j+=2){
  /*
    c1=buffer[i*width+j];
	c2=buffer[i*width+j+1];
  */
    c1=buffer[i+height*j];
	c2=buffer[i+height*j+height];
 	sendData((c1 & 0x0ff0)>>4);
	sendData(((c1 & 0x000f)<<4) | ((c2 & 0x0f00)>>8));
	sendData((c2 & 0x00ff));   
  }
 }
}

void LCD12_send2(word color){
 	sendData((color & 0x0ff0)>>4);
	sendData(((color & 0x000f)<<4) | ((color & 0x0f00)>>8));
	sendData((color & 0x00ff));
}

void LCD12_send2x(word c1,word c2){
 	sendData((c1 & 0x0ff0)>>4);
	sendData(((c1 & 0x000f)<<4) | ((c2 & 0x0f00)>>8));
	sendData((c2 & 0x00ff));
}

void LCD12_char(byte x,byte y,word ink,word paper,byte n){
 int ml,i;
 word a,b;
 y+=2;
 x &= 0xfe;
 sendCMD(PASET);
 sendData(y);
 sendData(y+7);
 sendCMD(CASET);
 sendData(x);
 sendData(x+7);
 sendCMD(RAMWR);
 for (ml=0;ml<8;ml++){
  i=FONT8x8F[n-32][ml];
  a=(i&0x80)?ink:paper;
  b=(i&0x40)?ink:paper;
  LCD12_send2x(a,b);
  a=(i&0x20)?ink:paper;
  b=(i&0x10)?ink:paper;
  LCD12_send2x(a,b);
  a=(i&0x08)?ink:paper;
  b=(i&0x04)?ink:paper;
  LCD12_send2x(a,b);
  a=(i&0x02)?ink:paper;
  b=(i&0x01)?ink:paper;
  LCD12_send2x(a,b);
 }
 LCD12_send2(paper);
}

void LCD12_string(byte x, byte y, word ink, word paper, char * str){
 x &= 0xfe;
 while(*str){
  LCD12_char(x,y,ink,paper,*str);
  str++;
  x+=8;
 }
}

void LCD12_clear(word color){  
	int i;
	int c1,c2,c3;

	c1=(color & 0x0ff0)>>4;
	c2=((color & 0x000f)<<4) | ((color & 0x0f00)>>8);
	c3=(color & 0x00ff);

    sendCMD(PASET);   // page start/end ram
  	sendData(0);            // for some reason starts at 2
  	sendData(131);          
  
  	sendCMD(CASET);   // column start/end ram
  	sendData(0);          
  	sendData(131);


  	sendCMD(RAMWR);    // write some stuff (background)
  	for (i = 0; i < 17424; i++){
		sendData(c1);
		sendData(c2);
		sendData(c3);
  	}
}
